#include <math.h>
#include <glib/gi18n.h>
#include <gtk/gtk.h>
#include "demo.h"


//derived from pango-html-1.42.4/pango-Cairo-Rendering.html
static gboolean on_draw(GtkWidget *widget, cairo_t *cr, gpointer data)
{
    guint width, height;
    // GdkRGBA color;
    GtkStyleContext *context;


    context = gtk_widget_get_style_context (widget);
    width = gtk_widget_get_allocated_width (widget);
    height = gtk_widget_get_allocated_height (widget);
    g_print("on_draw()....width=%d,height=%d\n", width, height);


    gtk_render_background (context, cr, 0, 0, width, height);

     //draw glyphString

    cairo_save (cr);
    cairo_translate (cr, 10, 200);

    draw_coord(cr, 0, 0);

    cairo_set_source_rgb(cr, 1, 0, 0);

    //#1.itemize


    // double base_x = 0;
    // double base_y = 0;
    double offset_x = 0;
    double offset_y = 0;
    // gint count = 0;

    PangoContext *pango_context;
    PangoFontDescription *desc;
    GList *items;
    GList *l;
    PangoItem *item;
    PangoGlyphString *glyphs;
    PangoRectangle ink_rect, logical_rect;
    // cairo_glyph_t stack_glyphs[256];    //buffer
    // cairo_glyph_t *cairo_glyphs = stack_glyphs;

    pango_context = gtk_widget_create_pango_context(widget);
    desc = pango_font_description_from_string("Sans 24");
    pango_context_set_font_description (pango_context, desc);
    char *str =pango_font_description_to_string(desc);
    g_print("fontDesc = %s\n", str);
    pango_font_description_free (desc);


    // PangoLanguage *zh_lang = pango_language_from_string("zh-cn");
    // PangoScript script = g_unichar_get_script(0x4e2d);

#if 0
    PangoAttrList *attrlist;
    PangoAttribute *attr;
    attrlist = pango_attr_list_new ();
    attr = pango_attr_language_new (pango_language_from_string ("zh-cn"));
    attr->start_index = 1;
    attr->end_index = 2;
    pango_attr_list_insert(attrlist, attr);


    pango_attr_list_unref(attrlist);
#endif

    // itemize

    char* text2= "Hi中国,yeah!\nHello.";      
    int len = strlen(text2);
    g_print("text2 len=%d\n", len);
    items = pango_itemize(pango_context, text2, 0, len, NULL, NULL);


    // 在linebreak处split item

    PangoLogAttr *logAttrs;
    len = g_utf8_strlen(text2, -1);
    logAttrs = g_new0(PangoLogAttr, len+1);

    pango_get_log_attrs(text2, -1, 0, pango_language_get_default(), logAttrs, len+1);

    int i;
    for(i = 0; i< len+1; i++)
    {
      g_print("%d: %s%s%s%s%s%s%s%s%s%s%s%s%s\n", i
              , logAttrs[i].is_line_break ? "lineBreak, ":""
              , logAttrs[i].is_mandatory_break ? "mandatoryBreak, ":""
              , logAttrs[i].is_char_break ? "charBreak, ":""
              , logAttrs[i].is_white ? "white, ":""
              , logAttrs[i].is_cursor_position ? "cursorPos, ":""
              , logAttrs[i].is_word_start ? "workStart, ":""
              , logAttrs[i].is_word_end ? "workEnd, ":""
              , logAttrs[i].is_sentence_boundary ? "sentenceBoundary, ":""
              , logAttrs[i].is_sentence_start ? "sentenceStart, ":""
              , logAttrs[i].is_sentence_end ? "sentenceEnd, ":""
              , logAttrs[i].backspace_deletes_character ? "backspaceDeletesChar, ":""
              , logAttrs[i].is_expandable_space ? "expandableSpace, ":""
              , logAttrs[i].is_word_boundary ? "wordBoundary, ":""
              );

      if(logAttrs[i].is_mandatory_break)      //zf, '/n'后随的字符其logAttr具有is_mandatory_break.
      {
        int count = 0;
        for(l = items; l; l=l->next)
        {
          item = l->data;
          g_assert(item);
          if(i > count && i < count + item->num_chars)
          {
            gchar *p = g_utf8_offset_to_pointer(text2, i);
            PangoItem *newItem;
            g_print("%ld, %d\n", p - text2 - item->offset, i-count);
            newItem = pango_item_split(item, p - text2 - item->offset, i-count);
            items = g_list_insert_before(items, l, newItem);
            break;
          }
          count += item->num_chars;
        }
      }
    }
    // for(i = 0; i< len+1; i++)
    // {
    //   if(logAttrs[i].is_line_break)
    //   {
    //     int count = 0;
    //     for(l = items; l; l=l->next)
    //     {
    //       item = l->data;
    //       if(i >= count && i < count + item->num_chars)
    //       {
    //         gchar *p = g_utf8_offset_to_pointer(text2, i);
    //         PangoItem *newItem;
    //         newItem = pango_item_split(item, p - text2 - item->offset, i-count);
    //         items = g_list_insert_before(items, l, newItem);
    //         break;
    //       }
    //       count += item->num_chars;
    //     }
    //   }
    // }




    glyphs = pango_glyph_string_new();
    
    int count = 0;
    i = 0;
    for(l = items; l; l=l->next)
    {
      g_print("%d:", ++i);
      item = l->data;
      g_print("index=%d, len=%d, num=%d, script=%d, lang=%s,\n"
                , item->offset, item->length, item->num_chars
                , item->analysis.script
                , pango_language_to_string(item->analysis.language));

      pango_shape(text2+item->offset, item->length, &item->analysis, glyphs);

      pango_glyph_string_extents(glyphs, item->analysis.font, &ink_rect, &logical_rect);
      g_print("rect=%d,%d,%d,%d\n"
                , PANGO_PIXELS(logical_rect.x)
                , PANGO_PIXELS(logical_rect.y)
                , PANGO_PIXELS(logical_rect.width)
                , PANGO_PIXELS(logical_rect.height));

      if(logAttrs[count].is_mandatory_break)
      {
        g_print("linebreak at %d\n", count);
        offset_x = 0;
        offset_y += PANGO_PIXELS(logical_rect.height);    //此处应该使用上一item的height.
      }

      cairo_move_to(cr, offset_x, offset_y);
      pango_cairo_show_glyph_string(cr, item->analysis.font, glyphs);

      offset_x += PANGO_PIXELS(logical_rect.width);

      count += item->num_chars;



      //offset_y += PANGO_PIXELS(logical_rect.height)
    //   pango_cairo_show_glyph_item(cr, text2, item);

#if 0
      for(int i = 0; i< glyphs->num_glyphs; i++)
      {
        PangoGlyphInfo *gi = &glyphs->glyphs[i];        

        if (gi->glyph != PANGO_GLYPH_EMPTY)
          {
            double cx = base_x + (double)(offset_x + gi->geometry.x_offset) / PANGO_SCALE;
            double cy = gi->geometry.y_offset == 0 
                            ? base_y 
                            : base_y + (double)(gi->geometry.y_offset) / PANGO_SCALE;

            if (gi->glyph & PANGO_GLYPH_UNKNOWN_FLAG)
            {

            }
            else
            {
              cairo_glyphs[count].index = gi->glyph;
              cairo_glyphs[count].x = cx;
              cairo_glyphs[count].y = cy;
              count++;
            }

          }
        offset_x += gi->geometry.width;
      }


      cairo_show_glyphs (cr, cairo_glyphs, count);
#endif      
    }

    pango_glyph_string_free(glyphs);

    g_free(logAttrs);

    g_list_free_full(items, (GDestroyNotify)pango_item_free);    
    g_object_unref(pango_context);


    cairo_restore(cr);

    return FALSE;
}

void do_pango_glyphs(GtkBox *parent)
{
    GtkWidget* frame;
    GtkWidget* drawing_area;

    frame = gtk_frame_new("pango glyphs");
    gtk_container_set_border_width(GTK_CONTAINER(frame), 10);
    gtk_box_pack_start(parent, frame, TRUE, TRUE, 0);

    drawing_area = gtk_drawing_area_new();
    gtk_container_add(GTK_CONTAINER(frame), drawing_area);

    g_signal_connect(drawing_area, "draw", G_CALLBACK (on_draw), NULL);        

    gtk_widget_show_all(GTK_WIDGET(parent));    
}